/*
 * Copyright (C) 2007-2008 SlideMe client
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.slideme.android.manager.discovery;

import android.util.Log;
import org.slideme.android.manager.ApplicationManagerContext;
import org.slideme.android.manager.download.ImageDownloadUserAgent;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

/**
 * Provides services for obtaining content bundle info.
 */
public interface DiscoveryContext {

    /**
     * Returns content bundle info from the specified URI. Should follow the format:
     *
     * @param serverURI the uri reference of the content bundle info.
     * @return content bundle info from the specified URI.
     * @throws IOException if there is an I/O problem
     */
    public ContentBundles getBundlesFor(URI serverURI) throws IOException;

    /**
     * Initializes the discovery context.
     *
     * @param context the application manager context
     */
    public void init(ApplicationManagerContext context);

    public static class Factory {
        /**
         * Constructor
         */
        private Factory() {
        }

        /**
         * Returns a default instance of the discovery context.
         *
         * @return a default instance of the  discovery context
         */
        public static DiscoveryContext createDefaultDiscoveryContext() {
            return new DiscoveryContext() {

                private ApplicationManagerContext context;

                public void init(ApplicationManagerContext context) {
                    if (context == null) {
                        throw new IllegalArgumentException("context");
                    }
                    this.context = context;
                }

                public ContentBundles getBundlesFor(URI serverURI) throws IOException {
                    if (serverURI == null) {
                        throw new IllegalArgumentException("serverURI");
                    }
                    URL url = serverURI.toURL();
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    ContentBundles contentBundles =
                            BundlesMarshaller.Factory.createDefaultBundlesMarshaller().marshal(connection.getInputStream());
                    ImageDownloadUserAgent agent = new ImageDownloadUserAgent();
                    agent.init(context.getDownloadContext());

                    for (ContentBundle contentBundle : contentBundles.getContentBundle()) {
                        String iconUri = contentBundle.getIcon();
                        if (iconUri != null) {
                            URI s;
                            try {
                                s = new URI(iconUri);
                            } catch (URISyntaxException e) {
                                Log.i("DiscoveryContext", "Icon URI is incorrect");
                                continue;
                            }
                            Log.i("DiscoveryContext", "Downloading icon: URI = " + contentBundle.getBundleId());
                            agent.downloadContent(s);
                            String fileName = getParamValueFromUri(iconUri, "fileName");
                            if (fileName == null) {
                                Log.d("DiscoveryContext", "URI does not contain a file name.");
                                fileName = contentBundle.getBundleId() + ".png";
                            }
                            contentBundle.setIconFileUri(fileName);
                        } else {
                            Log.i("DiscoveryContext", "Unable to locate icon for bundle: Bundle ID = "
                                    + contentBundle.getBundleId());
                        }
                    }
                    return contentBundles;
                }

                private String getParamValueFromUri(String uri, String paramName) {
                    String[] tokens = uri.split("&");
                    for (String s : tokens) {
                        if (s.startsWith(paramName)) {
                            String[] paramToken = s.split("=");
                            return paramToken[1];
                        }
                    }
                    return null;
                }
            };
        }
    }
}
